home *** CD-ROM | disk | FTP | other *** search
Java Source | 2000-08-01 | 14.9 KB | 578 lines |
- /*
- * eCross.java - A GameBoy's "Mario's Picross" clone
- * Copyright (C) 2000 Romain Guy
- * guy.romain@bigfoot.com
- * www.jext.org
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
- import waba.io.*;
- import waba.fx.*;
- import waba.ui.*;
- import waba.sys.*;
-
- /**
- * eCross is a reflexion game inspired from one, in my humble opinion,
- * of the best Nintendo GameBoy's games: Mario's Picross.<p>
- * In this game, the player has to find out the hidden picture by
- * filling in boxes in a grid according to the informations given next
- * to the game area.
- * @author Romain Guy <guy.romain@bigfoot.com>
- * @version 1.1
- */
-
- public class eCross extends MainWindow
- {
- ///////////////////////////////////////////////////////////////////////////////////////////////
- // CONSTANTS
- ///////////////////////////////////////////////////////////////////////////////////////////////
- // state
- private static final byte WAIT_FOR_START = 0, LEVEL_FINISHED = 1, PLAYING = 2;
- private byte state = WAIT_FOR_START;
-
- ///////////////////////////////////////////////////////////////////////////////////////////////
- // PRIVATE FIELDS
- ///////////////////////////////////////////////////////////////////////////////////////////////
- // the grid
- private Grid grid;
- // decoration
- private Wall wall;
- // timer
- private BackCounter timer;
- private boolean setTimer;
-
- // levels
- private LevelsManager levels;
- // selector
- private LevelSelector selector;
- // level number
- private int level = 0;
- // the loss in minutes
- private byte loss = -2;
-
- // the title bar
- private Title title;
-
- // tools
- private Tool tool;
- // exit button
- private Exit exit;
- // info
- private Info info;
-
- // drawing area
- private Image bufferImage;
- private Graphics g, bufferGraphics;
-
- ///////////////////////////////////////////////////////////////////////////////////////////////
- // INHERITED METHODS
- ///////////////////////////////////////////////////////////////////////////////////////////////
-
- /**
- * When the application starts, we create the drawing areas
- * and the back buffer (to avoid flickering). We also initialize
- * the grid (game area).
- */
-
- public void onStart()
- {
- // bakc buffering
- g = new Graphics(this);
- bufferImage = new Image(this.width, this.height);
- bufferGraphics = new Graphics(bufferImage);
-
- // splash
- Image splash = new Image("datas/splash.bmp");
- g.drawImage(splash, 16, 4);
- FontMetrics fm = getFontMetrics(this.defaultFont);
- String copyright = new String("(C)2000 Romain Guy - www.jext.org");
- g.drawText(copyright,
- (this.width - fm.getTextWidth(copyright)) / 2,
- this.height - (fm.getHeight() * 2) - 2);
- copyright = new String("(C)2000 Benjamin Rigaud - beno.ctw.cc");
- g.drawText(copyright,
- (this.width - fm.getTextWidth(copyright)) / 2,
- this.height - fm.getHeight());
-
- splash.free();
- splash = null;
-
- Vm.setSystemKeysUse(true);
-
- // GUI
- title = new Title("eCross v1.1");
- title.setRect(0, 0, this.width, 15);
-
- tool = new Tool();
- exit = new Exit();
-
- timer = new BackCounter(this, Wall.PATTERN_WIDTH + 2, 15 + 2 + Wall.PATTERN_HEIGHT);
- tool.setRect(Wall.PATTERN_WIDTH + 2, 15 + 2 + Wall.PATTERN_HEIGHT + 15 + 1, 17, 15);
- exit.setRect(Wall.PATTERN_WIDTH + 2 + 17 + 1, 15 + 2 + Wall.PATTERN_HEIGHT + 15 + 1, 17, 15);
- wall = new Wall(this.width, this.height);
- info = new Info();
-
- grid = new Grid(width - (15 * Grid.CELL_WIDTH + 16 + Wall.PATTERN_WIDTH + 2),
- height - (15 * Grid.CELL_WIDTH + 16 + Wall.PATTERN_HEIGHT + 2),
- this);
-
- levels = new LevelsManager("eCross Levels.eCrs.eCrs");
- selector = new LevelSelector("eCross Levels.eCrs.eCrs");
- int box = title.getBoxWidth(this);
- selector.setRect(box, 0, this.width - (box + 10 + 1), 15);
-
- Catalog _save = new Catalog("eCross Save.eCrs.eCrs", Catalog.READ_ONLY);
- if (_save.isOpen())
- {
- _save.setRecordPos(0);
-
- // level number
- byte[] b = new byte[1];
- _save.readBytes(b, 0, 1);
- level = (int) b[0];
-
- // level number
- b = new byte[1];
- _save.readBytes(b, 0, 1);
- loss = b[0];
-
- // current time
- b = new byte[2];
- _save.readBytes(b, 0, 2);
- timer.setTime(b[0], b[1]);
- setTimer = true;
-
- // what user did
- b = new byte[15 * 15];
- _save.readBytes(b, 0, b.length);
-
- setLevel();
- grid.setUserLevel(b);
-
- _save.close();
- //_save.delete();
-
- } else
- setLevel();
-
- paint();
- draw();
- }
-
- /**
- * Clears the area and performs painting.
- */
-
- public void onPaint(Graphics g)
- {
- clearBuffer();
- paint();
- //clear();
- draw();
- }
-
- /**
- * Free the resources taken by the drawing areas and saves, if needed, the
- * current game to get back to it later on.
- */
-
- public void onExit()
- {
- if (state == PLAYING)
- {
- byte m = timer.getMinutes();
- byte s = timer.getSeconds();
-
- Catalog _save = new Catalog("eCross Save.eCrs.eCrs", Catalog.CREATE);
- _save.addRecord(1 + 1 + 2 + 15 * 15);
- // level number
- _save.writeBytes(new byte[] { (byte) level }, 0, 1);
- // time loss
- _save.writeBytes(new byte[] { loss }, 0, 1);
- // current time
- _save.writeBytes(new byte[] { m, s }, 0, 2);
- // what user did
- _save.writeBytes(grid.getUserLevel(), 0, 15 * 15);
- _save.close();
- } else {
- Catalog _save = new Catalog("eCross Save.eCrs.eCrs", Catalog.WRITE_ONLY);
- _save.delete();
- }
-
- timer.stop();
-
- clear();
- g.free();
-
- clearBuffer();
- bufferGraphics.free();
- bufferImage.free();
-
- MiniString.free();
- tool.free();
- info.free();
- selector.free();
- wall.free();
- }
-
- /**
- * Handles events from user. Here we catch <code>PEN_UP</code>,
- * <code>PEN_DOWN</code> and <code>KEY_PRESS</code> (this can be
- * done because eCross is targeted to be used with WabaVM 1.0G from
- * <b>Guilherme Hazan</b>).
- * @param event The <code>Event</code> type
- */
-
- public void onEvent(Event event)
- {
- switch (event.type)
- {
- /*
- * PEN UP
- */
- case PenEvent.PEN_UP:
- PenEvent uevt = (PenEvent) event;
-
- // if chooser clicked on info icon or other
- if (info.handlePenUpEvent(g, uevt.x, uevt.y))
- {
- info.showInfo(this, g);
- }
- return;
-
- /*
- * PEN DOWN
- */
- case PenEvent.PEN_DOWN:
- PenEvent evt = (PenEvent) event;
-
- // if user tapped a reactive area
- if (selector.handlePenEvent(this, g, evt.x, evt.y) ||
- info.handlePenEvent(this, g, evt.x, evt.y) ||
- exit.handlePenEvent(this, g, evt.x, evt.y) )
- {
- return;
- }
-
- switch (state)
- {
- case WAIT_FOR_START:
- if (timer.state == BackCounter.STOPPED)
- {
- timer.start(setTimer);
- if (setTimer)
- setTimer = false;
- state = PLAYING;
- }
- break;
- case PLAYING:
- if (tool.handlePenEvent(evt.x, evt.y))
- tool.switchToolForward(this, bufferGraphics);
- else if (!grid.handlePenEvent(tool.getTool(), evt.x, evt.y))
- timer.remove(loss < 8 ? loss += 2 : loss);
- break;
- case LEVEL_FINISHED:
- levelFinished();
- //repaint();
- }
-
- break;
-
- /*
- * KEY PRESSED
- */
- case KeyEvent.KEY_PRESS:
- KeyEvent kevt = (KeyEvent) event;
-
- switch (kevt.key)
- {
- /*
- * HARD KEY 1 PRESSED (agenda)
- */
- case IKeys.HARD1:
- if (state == PLAYING)
- tool.switchToolForward(this, bufferGraphics);
- break;
-
- /*
- * HARD KEY 2 PRESSED (contacts)
- */
- case IKeys.HARD2:
- if (state == PLAYING)
- tool.switchToolBackward(this, bufferGraphics);
- break;
- }
-
- break;
- }
- }
-
- ///////////////////////////////////////////////////////////////////////////////////////////////
- // PUBLIC METHODS
- ///////////////////////////////////////////////////////////////////////////////////////////////
-
- /*
- * Defines some settings to begin a new level.
- */
-
- public void levelFinished()
- {
- loss = -2;
- state = WAIT_FOR_START;
- timer.reset();
- onPaint(g);
- }
-
- /**
- * Re-draws the timer by copying the timer rectangle from back buffered image
- * to screen. This avoids to repaint whole screen every second.
- * @param w The width of the timer
- * @param h The height of the timer
- */
-
- public void drawTimer(int w, int h)
- {
- g.copyRect(bufferImage, Wall.PATTERN_WIDTH + 2, 15 + 2 + Wall.PATTERN_HEIGHT,
- w, h, Wall.PATTERN_WIDTH + 2, 15 + 2 + Wall.PATTERN_HEIGHT);
- }
-
- /**
- * Pauses the counter. Used when showing a modal window
- * such as exit dialog or so.
- */
-
- public void pauseTimer()
- {
- timer.pause();
- }
-
- /**
- * Resumes the timer count. Called when a modal window
- * is closed.
- */
-
- public void resumeTimer()
- {
- timer.resume();
- }
-
- /**
- * Re-draws the tool by copying the timer rectangle from back buffered image
- * to screen. This avoids to repaint whole screen every second.
- */
-
- public void drawTool()
- {
- g.copyRect(bufferImage, Wall.PATTERN_WIDTH + 2, (15 + 2) * 2 + Wall.PATTERN_HEIGHT,
- 17, 15, Wall.PATTERN_WIDTH + 2, (15 + 2) * 2 + Wall.PATTERN_HEIGHT);
- }
-
- /**
- * Sets current level.
- * @param level Level number in defaut levels database
- */
-
- public void setLevel(int level)
- {
- this.level = level;
- setLevel();
- }
-
- /**
- * Returns current level.
- */
-
- public int getLevel()
- {
- return this.level;
- }
-
- /**
- * Called by the grid whenever the player has discovered
- * every single cell of the picture
- * @param picture The level content
- * @param name The level name
- */
-
- public void win(byte[] picture, String name)
- {
- byte m = timer.getMinutes();
- byte s = timer.getSeconds();
-
- timer.stop();
-
- int x = 47;
- int y = 15 + 40;
-
- bufferGraphics.setColor(255, 255, 255);
- bufferGraphics.fillRect(x - 1, y - 1, 64, 64);
-
- bufferGraphics.setColor(0, 0, 0);
- bufferGraphics.drawRect(x, y, 62, 62);
- bufferGraphics.drawRect(x + 16, y + 16, 31, 31);
-
- bufferGraphics.setFont(this.defaultFont);
- FontMetrics fm = getFontMetrics(this.defaultFont);
- bufferGraphics.drawText(name, x + 1 + (61 - fm.getTextWidth(name)) / 2,
- y + 46 + (16 - fm.getHeight()) / 2);
-
- if (grid.isHighScore(m, s))
- {
- String h = new String("Best Time !");
- bufferGraphics.drawText(h, x + 1 + (61 - fm.getTextWidth(h)) / 2,
- y + (16 - fm.getHeight()) / 2);
- Catalog _levels = new Catalog("eCross Levels.eCrs.eCrs", Catalog.WRITE_ONLY);
- _levels.setRecordPos(level);
- _levels.writeBytes(new byte[] { m, s }, 0, 2);
- _levels.close();
- }
-
- for (int i = 0; i < 15; i++)
- {
- int _y = y + 16 + (i * 2);
- for (int j = 0; j < 15; j++)
- {
- if (picture[i * 15 + j] == 1)
- bufferGraphics.fillRect(x + 16 + (j * 2), _y, 2, 2);
- }
- }
-
- if (++level == levels.getLevelsCount())
- level = 0;
-
- loss = -2;
-
- setLevel();
- state = LEVEL_FINISHED;
- draw();
- }
-
- /**
- * Called by <code>BackCounter</code> when remaining time is out.
- */
-
- public void timeOut()
- {
- int x = 47;
- int y = 15 + 40;
-
- bufferGraphics.setColor(255, 255, 255);
- bufferGraphics.fillRect(x - 1, y - 1, 64, 64);
-
- bufferGraphics.setColor(0, 0, 0);
- bufferGraphics.drawRect(x, y, 62, 62);
-
- bufferGraphics.setFont(this.defaultFont);
- FontMetrics fm = getFontMetrics(this.defaultFont);
- String gameover = new String("Time Out !");
- bufferGraphics.drawText(gameover, x + (62 - fm.getTextWidth(gameover)) / 2,
- y + (62 - fm.getHeight()) / 2);
-
- loss = -2;
-
- state = LEVEL_FINISHED;
- grid.reset();
- draw();
- timer.reset();
- }
-
- /**
- * Returns the back buffer drawing surface.
- */
-
- public Graphics getBackBuffer()
- {
- return bufferGraphics;
- }
-
- /**
- * Clears the back buffer.
- */
-
- public void clearBuffer()
- {
- bufferGraphics.setColor(255, 255, 255);
- bufferGraphics.fillRect(0, 0, this.width, this.height);
- }
-
- /**
- * Clears the drawing area.
- */
-
- public void clear()
- {
- g.setColor(255, 255, 255);
- g.fillRect(0, 0, this.width, this.height);
- }
-
- /**
- * Performs the draw of the back buffer onto
- * the drawing area.
- */
-
- public void draw()
- {
- g.drawImage(bufferImage, 0, 0);
- }
-
- /**
- * Paints every component.
- */
-
- public void paint()
- {
- title.paint(this, bufferGraphics);
- selector.paint(this, bufferGraphics);
- info.paint(bufferGraphics);
- wall.paint(bufferGraphics);
-
- grid.drawGrid();
- grid.drawCells();
-
- timer.paint(false);
- tool.paint(bufferGraphics);
- exit.paint(bufferGraphics);
- }
-
- ///////////////////////////////////////////////////////////////////////////////////////////////
- // PRIVATE METHODS
- ///////////////////////////////////////////////////////////////////////////////////////////////
-
- // sets the level by getting it from the LevelsManager.
- // then we display level number and high score on screen.
-
- private void setLevel()
- {
- Level l = levels.getLevel(level);
- grid.setLevel(l);
-
- StringBuffer buf = new StringBuffer("Level ").append(level + 1).append(' ').append('[');
-
- byte[] h = l.getHighScore();
-
- if (h[0] < 10)
- buf.append('0');
- buf.append(h[0]).append(':');
-
- if (h[1] < 10)
- buf.append('0');
-
- selector.setInfo(buf.append(h[1]).append(']').toString());
- }
- }
-
- // End of eCross.java
-